package cn.chiship.framework.upms.biz.user.service.impl;

import cn.chiship.framework.common.constants.CommonCacheConstants;
import cn.chiship.framework.common.util.FrameworkUtil2;
import cn.chiship.framework.upms.biz.base.service.UpmsUserCacheService;
import cn.chiship.framework.upms.biz.system.service.UpmsDataDictService;
import cn.chiship.framework.upms.biz.system.service.UpmsRegionService;
import cn.chiship.framework.upms.biz.user.entity.*;
import cn.chiship.framework.upms.biz.user.mapper.UpmsOrganizationMapper;
import cn.chiship.framework.upms.biz.user.pojo.dto.UpmsUserOrganizationDto;
import cn.chiship.framework.upms.biz.user.service.UpmsOrganizationService;
import cn.chiship.framework.upms.biz.user.service.UpmsUserOrganizationService;
import cn.chiship.sdk.cache.service.RedisService;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseCacheConstants;
import cn.chiship.sdk.core.enums.BaseResultEnum;
import cn.chiship.sdk.core.util.*;
import cn.chiship.sdk.framework.base.BaseServiceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * 组织业务接口实现层 2021/9/27
 *
 * @author lijian
 */
@Service
public class UpmsOrganizationServiceImpl extends BaseServiceImpl<UpmsOrganization, UpmsOrganizationExample>
		implements UpmsOrganizationService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UpmsOrganizationServiceImpl.class);

	@Resource
	UpmsOrganizationMapper upmsOrganizationMapper;

	@Resource
	UpmsUserOrganizationService upmsUserOrganizationService;

	@Resource
	UpmsDataDictService upmsDataDictService;

	@Resource
	UpmsRegionService upmsRegionService;

	@Resource
	RedisService redisService;

	@Resource
	private UpmsUserCacheService upmsCacheService;

	@Override
	public JSONObject assembleData(UpmsOrganization organization) {
		if (ObjectUtil.isEmpty(organization)) {
			return new JSONObject();
		}
		JSONObject json = JSON.parseObject(JSON.toJSONString(organization));
		String orgTag = organization.getOrganizationTag();
		List<String> orgTags = new ArrayList<>();
		if (!StringUtil.isNullOrEmpty(orgTag)) {
			String[] orgTagCodes = orgTag.split(",");
			for (String code : orgTagCodes) {
				orgTags.add(upmsDataDictService.getDictItemNameFromCache("organizationTag", code));
			}
		}
		json.put("_organizationTags", orgTags);
		json.put("_organizationCategory", upmsDataDictService.getDictItemNameFromCache("organizationCategory",
				organization.getOrganizationCategory()));
		json.put("_organizationLevel",
				upmsDataDictService.getDictItemNameFromCache("organizationLevel", organization.getOrganizationLevel()));
		json.put("_regionLevel1", upmsRegionService.getCacheRegionNameById(organization.getRegionLevel1()));
		json.put("_regionLevel2", upmsRegionService.getCacheRegionNameById(organization.getRegionLevel2()));
		json.put("_regionLevel3", upmsRegionService.getCacheRegionNameById(organization.getRegionLevel3()));
		json.put("_regionLevel4", upmsRegionService.getCacheRegionNameById(organization.getRegionLevel4()));
		upmsUserOrganizationService.getParentInfoByTreeNumber(organization.getTreeNumber(), json);
		return json;
	}

	@Override
	public BaseResult selectDetailsByPrimaryKey(Object id) {
		UpmsOrganization organization = selectByPrimaryKey(id);
		return BaseResult.ok(assembleData(organization));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BaseResult insertSelective(UpmsOrganization upmsOrganization) {
		BaseResult baseResult = generateTreeNumber(upmsOrganization.getPid());
		if (!baseResult.isSuccess()) {
			return baseResult;
		}
		upmsOrganization.setTreeNumber(baseResult.getData().toString());
		UpmsOrganizationExample upmsOrganizationExample = new UpmsOrganizationExample();
		upmsOrganizationExample.createCriteria().andOrganizationNameEqualTo(upmsOrganization.getOrganizationName())
				.andTypeEqualTo(upmsOrganization.getType());
		UpmsOrganizationExample.Criteria criteria = upmsOrganizationExample.createCriteria();
		criteria.andOrganizationCodeEqualTo(upmsOrganization.getOrganizationCode())
				.andTypeEqualTo(upmsOrganization.getType());
		upmsOrganizationExample.or(criteria);

		List<UpmsOrganization> upmsOrganizationList = upmsOrganizationMapper.selectByExample(upmsOrganizationExample);
		if (upmsOrganizationList.isEmpty()) {
			baseResult = super.insertSelective(upmsOrganization);
			if (baseResult.isSuccess()) {
				saveChargeInfo(upmsOrganization);
			}
			upmsCacheService.cacheOrganizations();
			return baseResult;
		}
		else {
			return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "编号或名称已存在，请重新输入");
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BaseResult updateByPrimaryKeySelective(UpmsOrganization upmsOrganization) {
		upmsOrganization.setGmtModified(System.currentTimeMillis());

		UpmsOrganizationExample upmsOrganizationExample = new UpmsOrganizationExample();
		upmsOrganizationExample.createCriteria().andOrganizationNameEqualTo(upmsOrganization.getOrganizationName())
				.andTypeEqualTo(upmsOrganization.getType()).andIdNotEqualTo(upmsOrganization.getId());
		UpmsOrganizationExample.Criteria criteria = upmsOrganizationExample.createCriteria();
		criteria.andOrganizationCodeEqualTo(upmsOrganization.getOrganizationCode())
				.andTypeEqualTo(upmsOrganization.getType()).andIdNotEqualTo(upmsOrganization.getId());
		upmsOrganizationExample.or(criteria);

		List<UpmsOrganization> upmsOrganizationList = upmsOrganizationMapper.selectByExample(upmsOrganizationExample);
		if (upmsOrganizationList.isEmpty()) {
			BaseResult baseResult = super.updateByPrimaryKeySelective(upmsOrganization);
			if (baseResult.isSuccess()) {
				saveChargeInfo(upmsOrganization);
			}
			upmsCacheService.cacheOrganizations();
			return baseResult;
		}
		else {
			return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "编号或名称已存在，请重新输入");
		}
	}

	@Override
	public BaseResult generateOrgCode(String pid, Byte type) {
		return BaseResult.ok(type + "-" + RandomUtil.number(5));
	}

	@Override
	public BaseResult generateTreeNumber(String pid) {
		String orgTreeNumber = FrameworkUtil2.generateTreeNumber(upmsOrganizationMapper.getTreeNumberByPid(pid));
		if (StringUtil.isNullOrEmpty(orgTreeNumber)) {
			return BaseResult.error("生成层级出错？");
		}
		return BaseResult.ok(orgTreeNumber);
	}

	@Override
	public BaseResult deleteByExample(UpmsOrganizationExample upmsOrganizationExample) {
		List<UpmsOrganization> upmsOrganizations = upmsOrganizationMapper.selectByExample(upmsOrganizationExample);
		super.deleteByExample(upmsOrganizationExample);
		List<String> orgIds = new ArrayList<>();
		for (UpmsOrganization organization : upmsOrganizations) {
			orgIds.add(organization.getId());
		}
		if (!orgIds.isEmpty()) {
			UpmsUserOrganizationExample upmsUserOrganizationExample = new UpmsUserOrganizationExample();
			upmsUserOrganizationExample.createCriteria().andOrganizationIdIn(orgIds);
			upmsUserOrganizationService.deleteByExample(upmsUserOrganizationExample);
		}
		upmsCacheService.cacheOrganizations();
		return BaseResult.ok();
	}

	@Override
	public BaseResult invitationCode(String id) {
		UpmsOrganization upmsOrganization = upmsOrganizationMapper.selectByPrimaryKey(id);
		if (StringUtil.isNull(upmsOrganization)) {
			return BaseResult.error("组织机构不存在，请确认参数！");
		}
		upmsOrganization.setInvitationCode(ShareCodeUtil.generateSerialCode(Long.valueOf(id)));
		super.updateByPrimaryKeySelective(upmsOrganization);
		return BaseResult.ok();
	}

	@Override
	public BaseResult getByInvitation(String code) {
		try {
			Long id = ShareCodeUtil.codeToId(code);
			UpmsOrganization upmsOrganization = upmsOrganizationMapper.selectByPrimaryKey(StringUtil.getString(id));
			return BaseResult.ok(upmsOrganization);
		}
		catch (Exception e) {
			return BaseResult.error("无效的邀请码！");
		}
	}

	@Override
	public BaseResult setChargePerson(String organizationId, String userId, String realName) {
		UpmsOrganization organization = upmsOrganizationMapper.selectByPrimaryKey(organizationId);
		if (StringUtil.isNull(organization)) {
			return BaseResult.error("组织机构不存在,请确认传递参数！");
		}
		organization.setChargeInfo(userId + ":" + realName);
		return super.updateByPrimaryKeySelective(organization);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BaseResult adjustment(String organizationId, String targetOrg) {
		UpmsOrganization organization = upmsOrganizationMapper.selectByPrimaryKey(organizationId);
		if (StringUtil.isNull(organization)) {
			return BaseResult.error("组织机构不存在,请确认传递参数！");
		}
		organization.setPid(targetOrg);
		UpmsOrganizationExample upmsOrganizationExample = new UpmsOrganizationExample();
		upmsOrganizationExample.createCriteria().andPidEqualTo(organizationId);
		if (upmsOrganizationMapper.countByExample(upmsOrganizationExample) > 0) {
			return BaseResult.error("该组织机构拥有子集，无法调整组织机构！");
		}
		BaseResult baseResult = generateTreeNumber(targetOrg);
		if (!baseResult.isSuccess()) {
			return baseResult;
		}
		organization.setTreeNumber(baseResult.getData().toString());

		return super.updateByPrimaryKeySelective(organization);
	}

	/**
	 * 将负责人关联到此机构下
	 * @param organization
	 */
	public void saveChargeInfo(UpmsOrganization organization) {
		String chargeInfo = organization.getChargeInfo();
		if (!StringUtil.isNullOrEmpty(organization.getChargeInfo())) {
			String[] chargeInfos = chargeInfo.split(":");
			String userId = chargeInfos.length > 1 ? chargeInfos[0] : chargeInfo;
			String orgId = organization.getId();
			UpmsUserOrganizationDto upmsUserOrganizationDto = new UpmsUserOrganizationDto();
			upmsUserOrganizationDto.setUserId(userId);
			upmsUserOrganizationDto.setOrganizationId(orgId);
			upmsUserOrganizationDto.setOrders(1);
			upmsUserOrganizationDto.setJob("负责人");
			upmsUserOrganizationService.saveUserOrganization(upmsUserOrganizationDto);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BaseResult removeOrg(List<String> orgIds) {
		if (orgIds.isEmpty()) {
			return BaseResult.error("集合不能为空");
		}
		// 删除组织
		UpmsOrganizationExample organizationExample = new UpmsOrganizationExample();
		organizationExample.createCriteria().andIdIn(orgIds);
		super.deleteByExample(organizationExample);

		// 删除组织用户
		UpmsUserOrganizationExample upmsUserOrganizationExample = new UpmsUserOrganizationExample();
		upmsUserOrganizationExample.createCriteria().andOrganizationIdIn(orgIds);
		upmsUserOrganizationService.deleteByExample(upmsUserOrganizationExample);
		return BaseResult.ok();
	}

	@Override
	public String cacheGetTreeNumberById(String orgId) {
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_ORG_PREFIX);
		UpmsOrganization organization = (UpmsOrganization) redisService.hget(key, orgId);
		if (ObjectUtil.isEmpty(organization)) {
			return null;
		}
		return organization.getTreeNumber();

	}

	@Override
	public void getParentInfoById(String orgId, JSONObject json) {
		getParentInfoByTreeNumber(cacheGetTreeNumberById(orgId), json);
	}

	@Override
	public void getParentInfoByTreeNumber(String treeNumber, JSONObject json) {
		if (StringUtil.isNullOrEmpty(treeNumber)) {
			return;
		}
		List<String> treeNumbers = FrameworkUtil2.getAllParentTreeNumber(treeNumber);
		String key = CommonCacheConstants.buildKey(BaseCacheConstants.REDIS_ORG_PREFIX);
		List<String> orgIds = new ArrayList<>();
		List<String> orgNames = new ArrayList<>();
		for (String tree : treeNumbers) {
			UpmsOrganization organization = (UpmsOrganization) redisService.hget(key, tree);
			orgIds.add(organization.getId());
			orgNames.add(organization.getOrganizationName());
		}
		json.put("_fullOrgIds", orgIds);
		json.put("_fullOrgNames", orgNames);
		json.put("_fullOrgId", StringUtil.join(orgIds, ","));
		json.put("_fullOrgName", StringUtil.join(orgNames, "/"));
	}

	@Override
	public String getOrgNameById(String orgId, Boolean isFull) {
		JSONObject json = new JSONObject();

		getParentInfoById(orgId, json);
		if (Boolean.TRUE.equals(isFull)) {
			return json.getString("_fullOrgName");
		}
		List<String> orgNames = json.getObject("_fullOrgNames", List.class);
		return orgNames.get(orgNames.size() - 1);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public BaseResult dissolution(String orgId) {
		/**
		 * 1.删除企业及下属企业 2.删除用户 3.删除用户与企业关联 4.删除用户与角色关联
		 */
		UpmsOrganization organization = selectByPrimaryKey(orgId);
		if (ObjectUtil.isEmpty(organization)) {
			return BaseResult.error("无效的企业标识");
		}
		UpmsOrganizationExample upmsOrganizationExample = new UpmsOrganizationExample();
		upmsOrganizationExample.createCriteria().andTreeNumberLike(organization.getTreeNumber() + "%");
		List<UpmsOrganization> organizations = upmsOrganizationMapper.selectByExample(upmsOrganizationExample);
		List<String> orgIds = new ArrayList<>();
		for (UpmsOrganization upmsOrganization : organizations) {
			orgIds.add(upmsOrganization.getId());
		}
		orgIds.add(orgId);
		upmsOrganizationMapper.deleteByExample(upmsOrganizationExample);

		UpmsUserOrganizationExample upmsUserOrganizationExample = new UpmsUserOrganizationExample();
		upmsUserOrganizationExample.createCriteria().andOrganizationIdIn(orgIds);
		List<UpmsUserOrganization> userOrganizations = upmsUserOrganizationService
				.selectByExample(upmsUserOrganizationExample);
		List<String> userIds = new ArrayList<>();
		for (UpmsUserOrganization upmsUserOrganization : userOrganizations) {
			userIds.add(upmsUserOrganization.getUserId());
		}
		upmsUserOrganizationService.deleteByExample(upmsUserOrganizationExample);

		/**
		 * 是否删除用户及角色，后期根据业务自行修改，此地方只删除企业及企业用户关联 考虑，同一个用户存在与多家企业问题
		 */
		PrintUtil.console("删除的用户", userIds);
		return BaseResult.ok();
	}

}
